{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "0f8b8e64-9334-432d-9b7f-d0f3c7bc478f",
   "metadata": {},
   "source": [
    "# Streaming Options\n",
    "\n",
    ":::{note}\n",
    "All the examples below require a live python process to experience the full interactivity of the plots.\n",
    ":::\n",
    "\n",
    "Options for handling live data streams:\n",
    "\n",
    "```{eval-rst}\n",
    ".. plotting-options-table:: Streaming Options\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8668be54-5ccd-4bf8-aa69-0da2674cba9f",
   "metadata": {},
   "source": [
    "(option-backlog)=\n",
    "## `backlog`\n",
    "\n",
    "The `backlog` option allows to define the maximum number of rows to keep in the stream buffer when using a streaming data source. Default is `1000`. The object returned when `stream` is set is a HoloViews [`DynamicMap`](inv:holoviews#reference/containers/bokeh/DynamicMap)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b386801-a5f3-4f24-90ad-8bac0722a69c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.streamz  # noqa\n",
    "from streamz.dataframe import Random\n",
    "\n",
    "df = Random(interval='200ms', freq='50ms')\n",
    "df.hvplot.table(width=400, backlog=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b399fc32-78e4-4571-ac50-3b16d456e77a",
   "metadata": {},
   "source": [
    "When running these two cells in a notebook one after the other, the data in the table above will be updated every 200ms for 2 seconds."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cb6df3b5-0020-4195-85d0-62ad85fcbc6d",
   "metadata": {},
   "outputs": [],
   "source": [
    "import asyncio\n",
    "await asyncio.sleep(2)\n",
    "df.stop()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36176689-9ee3-4c70-ae5d-8504277c27aa",
   "metadata": {},
   "source": [
    "(option-stream)=\n",
    "## `stream`\n",
    "\n",
    "The `stream` option accepts a stream object for streaming plots, allowing data updates without re-rendering the entire plot. The object returned when `stream` is set is a HoloViews [`DynamicMap`](inv:holoviews#reference/containers/bokeh/DynamicMap).\n",
    "\n",
    "In this first example, we set up and attach a HoloViews [`Pipe`](https://holoviews.org/user_guide/Streaming_Data.html#pipe) stream, we then call its `send` method in the next cell with a new DataFrame, which will entirely replace the plotted data, plotting a year after the other with an interval of 1 second."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "506a9785-04bb-449b-9f0a-9a5ac296aa57",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "from holoviews.streams import Pipe\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\")\n",
    "years = df.index.year.drop_duplicates()\n",
    "\n",
    "sdf = df.loc[str(years[0]), :]\n",
    "stream = Pipe(data=sdf)\n",
    "plot_opts = dict(height=250, width=500, xlim=(df.index.min(), df.index.max()), ylim=(0, 6))\n",
    "plot = sdf.hvplot.line(stream=stream, **plot_opts)\n",
    "plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14db1a5f-2b9c-4a4c-96f2-bb7b4d35b095",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "for year in years[1:]:\n",
    "    stream.send(df.loc[str(year), :])\n",
    "    time.sleep(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b229030-aec9-4500-b465-5f6fba3adfbf",
   "metadata": {},
   "source": [
    "In this second example we set up and attach a HoloViews [`Buffer`](https://holoviews.org/user_guide/Streaming_Data.html#buffer) stream, we then call its `send` method in the next cell with a new DataFrame, which will accumulate the data, gradually plotting the whole dataset with an interval of 1 second."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d5ef2720-e1e5-4124-9bda-2f9a73b628b7",
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "from holoviews.streams import Buffer\n",
    "\n",
    "df = hvplot.sampledata.stocks(\"pandas\").set_index(\"date\")\n",
    "years = df.index.year.drop_duplicates()\n",
    "\n",
    "sdf = df.loc[str(years[0]), :]\n",
    "stream = Buffer(data=sdf, index=False)\n",
    "plot_opts = dict(height=250, width=500, xlim=(df.index.min(), df.index.max()), ylim=(0, 6))\n",
    "plot = sdf.hvplot.line(stream=stream, **plot_opts)\n",
    "plot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "60af4458-e15b-4b97-90a7-aa534abbed97",
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "for year in years[1:]:\n",
    "    stream.send(df.loc[str(year), :])\n",
    "    time.sleep(1)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
